/*
 * Copyright 2002-2015 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.config;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.lang.Nullable;

/**
 * 为共享 bean 实例定义注册表的接口。
 * 可以通过 {@link org.springframework.beans.factory.BeanFactory} 实现来实现，以便以统一的方式公开它们的单例管理设施。
 *
 * <p> {@link ConfigurableBeanFactory} 接口扩展了这个接口。
 *
 * @author Juergen Hoeller
 * @see ConfigurableBeanFactory
 * @see org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
 * @see org.springframework.beans.factory.support.AbstractBeanFactory
 * @since 2.0
 */
public interface SingletonBeanRegistry {

	/**
	 * 在给定的 bean 名称下，在 bean 注册表中将给定的现有对象注册为单例。
	 * <p>
	 * 给定的实例应该被完全初始化；注册表不会执行任何初始化回调（特别是，它不会调用 {@link InitializingBean#afterPropertiesSet()} 方法）。
	 * 给定的实例也不会收到任何销毁回调（如 {@link DisposableBean#destroy()} 方法）。
	 * <p>
	 * 在完整的 BeanFactory 中运行时：<b>如果您的 bean 应该接收初始化和或销毁回调，则注册一个 bean 定义而不是现有实例<b>
	 * <p>
	 * 通常在注册表配置期间调用，但也可用于单例的运行时注册。
	 * 因此，注册表实现应该同步单例访问；如果它支持 BeanFactory 的单例延迟初始化，它无论如何都必须这样做。
	 *
	 * @param beanName        bean 的名字
	 * @param singletonObject 现有的单例对象
	 *
	 * @see InitializingBean#afterPropertiesSet
	 * @see DisposableBean#destroy
	 * @see org.springframework.beans.factory.support.BeanDefinitionRegistry#registerBeanDefinition
	 */
	void registerSingleton(String beanName, Object singletonObject);

	/**
	 * 返回在给定名称下注册的（原始）单例对象。
	 * <p>
	 * 只检查已经实例化的单例；不会为尚未实例化的单例 bean 定义返回对象。
	 * <p>
	 * 此方法的主要目的是访问手动注册的单例（参见 {@link #registerSingleton(String, Object)}）。
	 * 也可用于以原始方式访问由已创建的 BeanDefinition 定义的单例。
	 * <p><b>注意：<b> 此查找方法不知道 FactoryBean 前缀或别名。
	 * 在获取单例实例之前，您需要先解析规范的 bean 名称。
	 *
	 * @param beanName 要查找的 bean 的名称
	 *
	 * @return 注册的单例对象，如果没有找到则为 {@code null}
	 *
	 * @see ConfigurableListableBeanFactory#getBeanDefinition
	 */
	@Nullable
	Object getSingleton(String beanName);

	/**
	 * 检查此注册表是否包含具有给定名称的单例实例。
	 * <p>
	 * 只检查已经实例化的单例；对于尚未实例化的单例 bean 定义，不返回 {@code true}。
	 * <p>
	 * 此方法的主要目的是检查手动注册的单例（请参阅 {@link registerSingleton}）。也可用于检查由 bean 定义定义的单例是否已经创建。
	 * <p>
	 * 要检查 bean 工厂是否包含具有给定名称的 bean 定义，请使用 ListableBeanFactory 的 {@code containsBeanDefinition}。
	 * 同时调用 {@code containsBeanDefinition} 和 {@code containsSingleton} 可以回答特定的 bean 工厂是否包含具有给定名称的本地 bean 实例。
	 * <p>使用 BeanFactory 的 {@code containsBean} 进行常规检查，工厂是否知道具有给定名称的 bean（无论是手动注册的单例实例还是由 bean 定义创建的），还检查祖先工厂。
	 * <p>
	 * <b>注意：<b> 此查找方法不知道 FactoryBean 前缀或别名。在检查单例状态之前，您需要先解析规范的 bean 名称。
	 *
	 * @param beanName 要查找的 bean 的名称
	 *
	 * @return 如果此 bean 工厂包含具有给定名称的单例实例
	 *
	 * @see #registerSingleton
	 * @see org.springframework.beans.factory.ListableBeanFactory#containsBeanDefinition
	 * @see org.springframework.beans.factory.BeanFactory#containsBean
	 */
	boolean containsSingleton(String beanName);

	/**
	 * Return the names of singleton beans registered in this registry.
	 * <p>Only checks already instantiated singletons; does not return names
	 * for singleton bean definitions which have not been instantiated yet.
	 * <p>The main purpose of this method is to check manually registered singletons
	 * (see {@link #registerSingleton}). Can also be used to check which singletons
	 * defined by a bean definition have already been created.
	 *
	 * @return the list of names as a String array (never {@code null})
	 *
	 * @see #registerSingleton
	 * @see org.springframework.beans.factory.support.BeanDefinitionRegistry#getBeanDefinitionNames
	 * @see org.springframework.beans.factory.ListableBeanFactory#getBeanDefinitionNames
	 */
	String[] getSingletonNames();

	/**
	 * Return the number of singleton beans registered in this registry.
	 * <p>Only checks already instantiated singletons; does not count
	 * singleton bean definitions which have not been instantiated yet.
	 * <p>The main purpose of this method is to check manually registered singletons
	 * (see {@link #registerSingleton}). Can also be used to count the number of
	 * singletons defined by a bean definition that have already been created.
	 *
	 * @return the number of singleton beans
	 *
	 * @see #registerSingleton
	 * @see org.springframework.beans.factory.support.BeanDefinitionRegistry#getBeanDefinitionCount
	 * @see org.springframework.beans.factory.ListableBeanFactory#getBeanDefinitionCount
	 */
	int getSingletonCount();

	/**
	 * Return the singleton mutex used by this registry (for external collaborators).
	 *
	 * @return the mutex object (never {@code null})
	 *
	 * @since 4.2
	 */
	Object getSingletonMutex();

}
